package server

import (
	"context"
	"errors"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/danfwing/sd-project/pkg/config"
	"github.com/gin-gonic/gin"
)

type Server struct {
	engine *gin.Engine
	cfg    *config.Config
}

// NewServer 创建一个新的 gin server
func NewServer(cfg *config.Config, handler []gin.HandlerFunc) *Server {
	gin.SetMode(cfg.Server.Mode)
	engine := gin.New()

	// 使用 Recovery 中间件
	engine.Use(handler...)
	return &Server{
		engine: engine,
		cfg:    cfg,
	}
}

// Engine 获取 gin 引擎
func (s *Server) Engine() *gin.Engine {
	return s.engine
}

// Run 启动服务器
func (s *Server) Run() error {
	srv := &http.Server{
		Addr:    fmt.Sprintf("%s:%s", s.cfg.Server.Host, s.cfg.Server.Port),
		Handler: s.engine,
	}

	// 在goroutine中启动服务器
	go func() {
		if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			log.Printf("listen: %s\n", err)
		}
	}()

	// 等待中断信号以优雅地关闭服务器
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	log.Println("Shutting down server...")

	// 设置5秒的超时时间
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := srv.Shutdown(ctx); err != nil {
		return fmt.Errorf("server forced to shutdown: %v", err)
	}

	log.Println("Server exiting")
	return nil
}
